import CryptoJS from "crypto-js";
import { RoleUserI, UserI } from "@/types";
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

/**
 * 根据后台Casbin的Policy判断指定权限
 * @param policies: [object, tenant, subject, method][]
 * @param roles: [roleId, tenantId][]
 * @param subject
 * @param methods
 */
export const hasPermission = (
  user: UserI,
  subject: string,
  method: string
): boolean => {
  const { resources = [], roleUsers = [] } = user;
  if (user.id?.toString() === "1000") {
    return true;
  }
  for (let j = 0; j < resources.length; j++) {
    const resource = resources[j];
    // if (subject == "search_vbp_dept_duty_sql") {
    //   console.log(resource, " ", subject, " ", method);
    //   console.log(resource.methods == method);
    // }
    if (resource.name === subject && resource.methods === method) {
      // console.log("hit");
      return true;
    }
  }
  return false;
};

export const isValidJson = (jsonString: string): boolean => {
  try {
    JSON.parse(jsonString);
    return true; // 解析成功
  } catch (error) {
    return false; // 解析失败
  }
};

//
export const stringToHexArray = (str: string) => {
  var encoder = new TextEncoder();
  var uint8Array = encoder.encode(str);
  return Array.from(uint8Array, (byte) => {
    return byte.toString(16);
  });
};

// 定义密码强度校验规则
export const passwordStrengthTest = (password: string) => {
  const hasLowercase = /[a-z]/.test(password);
  const hasUppercase = /[A-Z]/.test(password);
  const hasNumber = /\d/.test(password);
  const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>_+=]/.test(password);

  return (
    !password ||
    (password.length >= 8 &&
      hasLowercase &&
      hasUppercase &&
      hasNumber &&
      hasSpecialChar)
  );
};

//
export const encryptStr = (str: string) => {
  // ENCRYPT_KEY: bytes = b"16_byte_encrypt_"
  // ENCRYPT_IV: bytes = b"16_byte_iv_54321"
  const encryptKey = CryptoJS.enc.Utf8.parse("16_byte_encrypt_");
  const encryptIv = CryptoJS.enc.Utf8.parse("16_byte_iv_54321");
  // console.log(encryptKey);
  // console.log(encryptIv);

  return CryptoJS.AES.encrypt(
    // CryptoJS.enc.Utf8.parse 主要用于将字符串转换为 UTF-8 编码的字节数组，
    // 以便后续加密操作可以正确处理。这一步骤是为了确保字符串数据在加密前的一致性和兼容性。
    // 在实际应用中，这是加密流程中常见的第一步，确保了字符串数据可以被加密算法正确处理。
    CryptoJS.enc.Utf8.parse(str),
    encryptKey,
    {
      iv: encryptIv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    }
  ).toString();
  // console.log(encryptedUsername);
};

export const decryptStr = (encryptedStr: string): string => {
  const encryptKey = CryptoJS.enc.Utf8.parse("med_gpt_encrypt_");
  const encryptIv = CryptoJS.enc.Utf8.parse("med_gpt_iv_54321");

  // 解密
  const decrypted = CryptoJS.AES.decrypt(encryptedStr, encryptKey, {
    iv: encryptIv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });

  // 将解密后的字节数组转换为 UTF-8 字符串
  const originalStr = CryptoJS.enc.Utf8.stringify(decrypted);

  return originalStr;
};
